/*线程的优雅退出*/
#include <47func.h>
#include "taskQueue.h"
#include "threadPool.h"

int pipefds[2];

void sighandler(int signum)
{
    printf("signum = %d\n", signum);
    write(pipefds[1], "1", 1); // 随便写入数据
}

int main(int argc, char *argv[])
{
    // ./server 192.168.111.128 1234 3
    ARGS_CHECK(argc, 4);
    
    pipe(pipefds);

    if(fork() != 0)
    {
        // 父进程 专门用来关闭
        close(pipefds[0]); // 关闭读端
        signal(SIGUSR1, sighandler);
        wait(NULL);
        exit(0);
    }

    close(pipefds[1]);

    // 为threadPool分配内存
    threadPool_t threadPool;

    // 初始化threadPool
    int workerNum = atoi(argv[3]);
    threadPoolInit(&threadPool, workerNum);

    // 创建子线程
    makeWorker(&threadPool);

    // 准备TCP连接
    int sockfd;
    tcpInit(argv[1], argv[2], &sockfd);

    int epfd = epoll_create(1);
    epollAdd(epfd, sockfd);
    epollAdd(epfd, pipefds[0]);
    struct epoll_event readyset[2];

    while(1)
    {
        int readyNum = epoll_wait(epfd, readyset, 2, -1);
        for(int i = 0; i < readyNum; ++i)
        {
            if(readyset[i].data.fd == sockfd)
            {
                int netfd = accept(sockfd, NULL, NULL);

                pthread_mutex_lock(&threadPool.taskQueue.mutex); // 加锁
                taskEnqueue(&threadPool.taskQueue, netfd);
                printf("main sent a new task!\n");

                pthread_cond_signal(&threadPool.taskQueue.cond);
                pthread_mutex_unlock(&threadPool.taskQueue.mutex);
            }
            else if(readyset[i].data.fd == pipefds[0])
            {
                // 线程池将要退出
                // 优雅退出
                pthread_mutex_lock(&threadPool.taskQueue.mutex);
                threadPool.exitflag = 1;
                pthread_cond_broadcast(&threadPool.taskQueue.cond);
                pthread_mutex_unlock(&threadPool.taskQueue.mutex);

                for(int j = 0; j < workerNum; ++j)
                {
                    pthread_join(threadPool.tidArr[j], NULL);
                }

                printf("main thread is going to die!\n");
                pthread_exit(NULL);
            }
        }
    }
}